﻿using System;
using System.Drawing;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using Felbot.Profiles;
using MBNCSUtil;

namespace Felbot.Interface {
    /// <summary>This class represents the profile configuration form, where the user can set options specific to each profile, or the global profile for those settings.</summary>
    public partial class frmProfileConfiguration : Form {
        private Profile m_Current;
        private string m_OldLabel;
        private bool m_ProfileSaved = true;

        /// <summary>
        /// Create a new profile configuration form.
        /// </summary>
        public frmProfileConfiguration() {
            InitializeComponent();
        }

        private void frmConfiguration_Load(object sender, EventArgs e) {
            LoadProfileList();
        }

        private void lvProfiles_SelectedIndexChanged(object sender, EventArgs e) {
            if (m_Current != null && !m_ProfileSaved) {
                if (MessageBox.Show("The current profile is not saved.\r\n" +
                                    "Do you want to save changes?",
                                    "Felbot",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1)
                        == DialogResult.Yes) {
                    SaveCurrentProfile();
                }
            }
            if (lvProfiles.SelectedItems.Count == 1) {
                LoadProfile(ProfileControl.GetProfile(lvProfiles.SelectedItems[0].Text));
                tcProfileControl.Show();
                btnProfileSave.Show();
                btnProfileCancel.Show();
                lblInfo.Text = "General profile settings.";
            } else {
                m_Current = null;
                tcProfileControl.Hide();
                btnProfileSave.Hide();
                btnProfileCancel.Hide();
                lblInfo.Text = "Select a profile to edit.";
            }
            btnProfileRemove.Enabled = (lvProfiles.Items.Count > 0);
            btnProfileExport.Enabled = (lvProfiles.Items.Count > 0);
        }

        private void lvProfiles_BeforeLabelEdit(object sender, LabelEditEventArgs e) {
            btnProfileRemove.Enabled = false;
            btnProfileAdd.Enabled = false;
            btnProfileImport.Enabled = false;
            btnProfileExport.Enabled = false;
            if (lvProfiles.Items[e.Item].Text == "GLOBAL") {
                e.CancelEdit = true;
            }
            m_OldLabel = lvProfiles.Items[e.Item].Text;
            tcProfileControl.Hide();
            btnProfileSave.Hide();
            btnProfileCancel.Hide();
            lblInfo.Text = "Edit profile name for " + m_OldLabel + ".";
        }

        private void lvProfiles_AfterLabelEdit(object sender, LabelEditEventArgs e) {
            lvProfiles.SelectedItems.Clear();
            btnProfileAdd.Enabled = true;
            btnProfileImport.Enabled = true;
            lvProfiles.Items[e.Item].Selected = true;
            if (e.Label == null)
                return;
            ProfileControl.GetProfile(m_OldLabel).ProfileName = e.Label;
            LoadProfile(ProfileControl.GetProfile(lvProfiles.SelectedItems[0].Text));
            lblInfo.Text = "General profile settings.";
        }

        private void LoadProfileList() {
            ListViewItem item;
            string status;
            item = new ListViewItem(new string[] { ProfileControl.Global.ProfileName, "Global" });
            item.ForeColor = Color.Gray;
            lvProfiles.Items.Add(item);
            foreach (Profile m_pProfile in ProfileControl.ProfileList) {
                if (m_pProfile.Open) {
                    status = "Open";
                } else {
                    status = "Closed";
                }
                item = new ListViewItem(new string[] { m_pProfile.ProfileName, status });
                item.ForeColor = Color.White;
                lvProfiles.Items.Add(item);
            }
        }

        private void LoadProfile(Profile profile) {
            if (profile == null) {
                profile = ProfileControl.Global;
                cbGeneralLoad.Enabled = false;
                txtConUsername.Enabled = false;
                txtConPassword.Enabled = false;
                cboConServer.Enabled = false;
                cboConClient.Enabled = false;
                txtConCdkey.Enabled = false;
                txtConExpCdkey.Enabled = false;
                cbAdvChangePass.Enabled = false;
                txtAdvChangePass.Enabled = false;
            } else {
                cbGeneralLoad.Enabled = true;
                txtConUsername.Enabled = true;
                txtConPassword.Enabled = true;
                cboConServer.Enabled = true;
                cboConClient.Enabled = true;
                txtConCdkey.Enabled = true;
                txtConExpCdkey.Enabled = true;
                cbAdvChangePass.Enabled = true;
                txtAdvChangePass.Enabled = true;
            }

            m_Current = profile;

            tcProfileControl.SelectTab(0);
            lblInfo.Text = "General profile settings.";

            //general tab
            txtGeneralName.Text = profile.ProfileName;
            cbGeneralLoad.Checked = profile.GetSetting("General", "LoadOnFelbotStart").ToLocalBoolean(false);
            cbGeneralConnect.Checked = profile.GetSetting("General", "ConnectOnProfileStart").ToLocalBoolean(false);
            #region PositionChoice
            switch (profile.GetSetting("General", "PositionChoice").ToInteger(0)) {
                case 0:
                default: //default
                    rbStartPosDefault.Checked = true;
                    break;
                case 1: //store
                    rbStartPosStore.Checked = true;
                    break;
                case 2: //custom
                    rbStartPosCustom.Checked = true;
                    break;
            }
            #endregion
            nudStartPosW.Value = (decimal) profile.GetSetting("General", "PositionW").ToInteger(800);
            nudStartPosH.Value = (decimal) profile.GetSetting("General", "PositionH").ToInteger(600);
            nudStartPosL.Value = (decimal) profile.GetSetting("General", "PositionL").ToInteger(200);
            nudStartPosT.Value = (decimal) profile.GetSetting("General", "PositionT").ToInteger(200);
            nudStartUserlistW.Value = (decimal) profile.GetSetting("General", "UserlistW").ToInteger(250);
            cboStartState.SelectedIndex = profile.GetSetting("General", "State").ToInteger(0);

            //connection tab
            txtConUsername.Text = profile.GetSetting("Connection", "Username").ToLocalString();
            txtConPassword.Text = profile.GetSetting("Connection", "Password").ToLocalString();
            cboConServer.Text = profile.GetSetting("Connection", "Server").ToLocalString();
            nudConPort.Value = (decimal) profile.GetSetting("Connection", "Port").ToLocalInteger(6112);
            #region cboConClient
            switch (profile.GetSetting("Connection", "Client").ToLocalString()) {
                default:
                    cboConClient.SelectedIndex = 0;
                    break;
                case "SSHR":
                    cboConClient.SelectedIndex = 1;
                    break;
                case "JSTR":
                    cboConClient.SelectedIndex = 2;
                    break;
                case "STAR":
                    cboConClient.SelectedIndex = 3;
                    break;
                case "SEXP":
                    cboConClient.SelectedIndex = 4;
                    break;
                case "DSHR":
                    cboConClient.SelectedIndex = 5;
                    break;
                case "DRTL":
                    cboConClient.SelectedIndex = 6;
                    break;
                case "D2DV":
                    cboConClient.SelectedIndex = 7;
                    break;
                case "D2XP":
                    cboConClient.SelectedIndex = 8;
                    break;
                case "W2BN":
                    cboConClient.SelectedIndex = 9;
                    break;
                case "WAR3":
                    cboConClient.SelectedIndex = 10;
                    break;
                case "W3XP":
                    cboConClient.SelectedIndex = 11;
                    break;
                case "CHAT":
                    cboConClient.SelectedIndex = 12;
                    break;
            }
            #endregion
            txtConCdkey.Text = profile.GetSetting("Connection", "CdKey").ToLocalString();
            txtConExpCdkey.Text = profile.GetSetting("Connection", "ExpCdKey").ToLocalString();
            cbConSpawn.Checked = profile.GetSetting("Connection", "Spawn").ToLocalBoolean(false);
            cbConUseTFTKey.Checked = profile.GetSetting("Connection", "TFTtoROCSwitch").ToLocalBoolean(false);
            cbConD2Realm.Checked = profile.GetSetting("Connection", "D2Realm").ToLocalBoolean(false);

            //advanced connection tab
            txtAdvKeyowner.Text = profile.GetSetting("AdvConn", "KeyOwner").ToLocalString("Felbot User");
            txtAdvEmail.Text = profile.GetSetting("AdvConn", "EmailAddress").ToLocalString();
            cbAdvChangePass.Checked = profile.GetSetting("AdvConn", "PasswordChange").ToLocalBoolean(false);
            txtAdvChangePass.Text = profile.GetSetting("AdvConn", "PasswordChangeTo").ToLocalString();
            cbAdvNoAutoCreate.Checked = profile.GetSetting("AdvConn", "NoAutoCreate").ToLocalBoolean(false);
            cbAdvSpoof.Checked = profile.GetSetting("AdvConn", "SpoofPing").ToLocalBoolean(false);
            cboAdvSpoof.SelectedIndex = profile.GetSetting("AdvConn", "SpoofPingTo").ToLocalInteger(0);
            cbAdvPlug.Checked = profile.GetSetting("AdvConn", "UdpPlug").ToLocalBoolean(false);
            txtAdvHashes.Text = profile.GetSetting("AdvConn", "Hashes").ToLocalString("\\Hashes\\");
            nudAdvVerbyte.Value = (decimal) profile.GetSetting("AdvConn", "Verbyte").ToLocalInteger(-1);
            cbAdvProxyUse.Checked = profile.GetSetting("AdvConn", "ProxyUse").ToLocalBoolean(false);
            cboAdvProxyProtocol.SelectedIndex = profile.GetSetting("AdvConn", "ProxyProtocol").ToLocalInteger(0);
            txtAdvProxyServer.Text = profile.GetSetting("AdvConn", "ProxyServer").ToLocalString();
            nudAdvProxyPort.Value = (decimal) profile.GetSetting("AdvConn", "ProxyPort").ToLocalInteger(1080);

            //automation tab
            txtCmdTrigger.Text = profile.GetSetting("Commands", "Trigger").ToLocalString("!");
            txtChanHome.Text = profile.GetSetting("Channel", "Home").ToLocalString();
            
            m_ProfileSaved = true;
            btnProfileSave.Enabled = false;
        }

        private void SaveCurrentProfile() {
            if (m_Current == null)
                return;

            m_ProfileSaved = true;
            btnProfileSave.Enabled = false;

            //general tab
            m_Current.SetSetting("General", "LoadOnFelbotStart", cbGeneralLoad.Checked);
            m_Current.SetSetting("General", "ConnectOnProfileStart", cbGeneralConnect.Checked);
            #region PositionChoice
            if (rbStartPosCustom.Checked)
                m_Current.SetSetting("General", "PositionChoice", 2);
            else if (rbStartPosStore.Checked)
                m_Current.SetSetting("General", "PositionChoice", 1);
            else
                m_Current.SetSetting("General", "PositionChoice", 0);
            #endregion
            m_Current.SetSetting("General", "PositionW", (int) nudStartPosW.Value);
            m_Current.SetSetting("General", "PositionH", (int) nudStartPosH.Value);
            m_Current.SetSetting("General", "PositionL", (int) nudStartPosL.Value);
            m_Current.SetSetting("General", "PositionT", (int) nudStartPosT.Value);
            m_Current.SetSetting("General", "UserlistW", (int) nudStartUserlistW.Value);
            m_Current.SetSetting("General", "State", cboStartState.SelectedIndex);

            //connection tab
            m_Current.SetSetting("Connection", "Username", txtConUsername.Text);
            m_Current.SetSetting("Connection", "Password", txtConPassword.Text);
            m_Current.SetSetting("Connection", "Server", cboConServer.Text);
            m_Current.SetSetting("Connection", "Port", (int) nudConPort.Value);
            #region cboConClient
            switch (cboConClient.Text) {
                case "StarCraft: Shareware":
                    m_Current.SetSetting("Connection", "Client", "SSHR");
                    break;
                case "StarCraft: Japan":
                    m_Current.SetSetting("Connection", "Client", "JSTR");
                    break;
                case "StarCraft":
                    m_Current.SetSetting("Connection", "Client", "STAR");
                    break;
                case "StarCraft: Broodwar":
                    m_Current.SetSetting("Connection", "Client", "SEXP");
                    break;
                case "Diablo: Shareware":
                    m_Current.SetSetting("Connection", "Client", "DSHR");
                    break;
                case "Diablo":
                    m_Current.SetSetting("Connection", "Client", "DRTL");
                    break;
                case "Diablo II":
                    m_Current.SetSetting("Connection", "Client", "D2DV");
                    break;
                case "Diablo II: Lord of Destruction":
                    m_Current.SetSetting("Connection", "Client", "D2XP");
                    break;
                case "WarCraft II: Battle.net Edition":
                    m_Current.SetSetting("Connection", "Client", "W2BN");
                    break;
                case "WarCraft III":
                    m_Current.SetSetting("Connection", "Client", "WAR3");
                    break;
                case "WarCraft III: The Frozen Throne":
                    m_Current.SetSetting("Connection", "Client", "W3XP");
                    break;
                case "Chat":
                    m_Current.SetSetting("Connection", "Client", "CHAT");
                    break;
                default:
                    m_Current.SetSetting("Connection", "Client", "");
                    break;
            }
            #endregion
            m_Current.SetSetting("Connection", "CdKey", txtConCdkey.Text);
            m_Current.SetSetting("Connection", "ExpCdKey", txtConExpCdkey.Text);
            m_Current.SetSetting("Connection", "Spawn", cbConSpawn.Checked);
            m_Current.SetSetting("Connection", "TFTtoROCSwitch", cbConUseTFTKey.Checked);
            m_Current.SetSetting("Connection", "D2Realm", cbConD2Realm.Checked);

            //advanced connection tab
            m_Current.SetSetting("AdvConn", "KeyOwner", txtAdvKeyowner.Text);
            m_Current.SetSetting("AdvConn", "EmailAddress", txtAdvEmail.Text);
            m_Current.SetSetting("AdvConn", "PasswordChange", cbAdvChangePass.Checked);
            m_Current.SetSetting("AdvConn", "PasswordChangeTo", txtAdvChangePass.Text);
            m_Current.SetSetting("AdvConn", "NoAutoCreate", cbAdvNoAutoCreate.Checked);
            m_Current.SetSetting("AdvConn", "SpoofPing", cbAdvSpoof.Checked);
            m_Current.SetSetting("AdvConn", "SpoofPingTo", cboAdvSpoof.SelectedIndex);
            m_Current.SetSetting("AdvConn", "UdpPlug", cbAdvPlug.Checked);
            m_Current.SetSetting("AdvConn", "Hashes", txtAdvHashes.Text);
            m_Current.SetSetting("AdvConn", "Verbyte", (int) nudAdvVerbyte.Value);
            m_Current.SetSetting("AdvConn", "ProxyUse", cbAdvProxyUse.Checked);
            m_Current.SetSetting("AdvConn", "ProxyProtocol", cboAdvProxyProtocol.SelectedIndex);
            m_Current.SetSetting("AdvConn", "ProxyServer", txtAdvProxyServer.Text);
            m_Current.SetSetting("AdvConn", "ProxyPort", (int) nudAdvProxyPort.Value);

            //automation tab
            m_Current.SetSetting("Commands", "Trigger", txtCmdTrigger.Text);
            m_Current.SetSetting("Channel", "Home", txtChanHome.Text);

            //save to file
            m_Current.SaveSettings();

            //is name changed?
            if (txtGeneralName.Text != m_Current.ProfileName) {
                //yes? change the list then the profile object
                foreach (ListViewItem item in lvProfiles.Items) {
                    if (item.Text == m_Current.ProfileName) {
                        //change profile name in list
                        item.Text = txtGeneralName.Text;
                    }
                }
                //change profile name and move file
                m_Current.ProfileName = txtGeneralName.Text;
            }
        }

        /// <summary>
        /// Creates a new profile.
        /// </summary>
        public void NewProfile() {
            string name = ProfileControl.GetMakeName;
            Profile profile = ProfileControl.MakeProfile(name);
            ListViewItem item = new ListViewItem(new string[] { profile.ProfileName, "Closed" });
            item.ForeColor = Color.White;
            lvProfiles.Items.Add(item);
            item.Selected = true;
        }

        /// <summary>
        /// Goes directly to editing the specified profile.
        /// </summary>
        /// <param name="a_pProfile">The name of the profile.</param>
        public void EditProfile(Profile profile) {
            foreach (ListViewItem item in lvProfiles.Items) {
                item.Selected = (item.Text.Equals(profile.ProfileName, StringComparison.CurrentCultureIgnoreCase));
            }
        }

        private void btnProfileAdd_Click(object sender, EventArgs e) {
            NewProfile();
        }

        private void btnProfileRemove_Click(object sender, EventArgs e) {
            foreach (ListViewItem item in lvProfiles.SelectedItems) {
                if (!item.Text.Equals("GLOBAL", StringComparison.CurrentCultureIgnoreCase)) {
                    ProfileControl.RemoveProfile(ProfileControl.GetProfile(item.Text));
                    item.Remove();
                }
            }
            btnProfileRemove.Enabled = false;
            btnProfileExport.Enabled = false;
        }

        private void btnProfileExport_Click(object sender, EventArgs e) {
            foreach (ListViewItem item in lvProfiles.SelectedItems) {
                Program.MainForm.ExportProfile(ProfileControl.GetProfile(item.Text));
            }
        }

        private void btnProfileSave_Click(object sender, EventArgs e) {
            SaveCurrentProfile();
            lvProfiles.SelectedItems.Clear();
        }

        private void btnProfileCancel_Click(object sender, EventArgs e) {
            m_ProfileSaved = true;
            lvProfiles.SelectedItems.Clear();
        }

        private void btnOK_Click(object sender, EventArgs e) {
            SaveCurrentProfile();
            lvProfiles.SelectedItems.Clear();
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e) {
            m_ProfileSaved = true;
            lvProfiles.SelectedItems.Clear();
            this.Close();
        }

        private void control_Enter(object sender, EventArgs e) {
            lblInfo.Text = tip.GetToolTip((Control) sender);
        }

        private void control_Changed(object sender, EventArgs e) {
            m_ProfileSaved = false;
            btnProfileSave.Enabled = true;
        }

        private void tcProfileControl_Selected(object sender, TabControlEventArgs e) {
            switch (e.TabPageIndex) {
                case 0: //general
                    lblInfo.Text = "General profile settings.";
                    break;
                case 1: //connection
                    lblInfo.Text = "Required connection settings.";
                    break;
                case 2: //advanced connection
                    lblInfo.Text = "Advanced connection settings.";
                    break;
                case 3: //commands
                    lblInfo.Text = "Command settings.";
                    break;
                case 4: //channel
                    lblInfo.Text = "Channel settings.";
                    break;
                case 5: //clan
                    lblInfo.Text = "Clan settings.";
                    break;
            }
        }

        private void rbStartPosDefault_CheckedChanged(object sender, EventArgs e) {
            control_Changed(sender, e);
            bool checkedValue = rbStartPosCustom.Checked;
            lblStartPosWH.Visible = checkedValue;
            nudStartPosW.Visible = checkedValue;
            lblStartPosWHx.Visible = checkedValue;
            nudStartPosH.Visible = checkedValue;
            lblStartPosLT.Visible = checkedValue;
            nudStartPosL.Visible = checkedValue;
            lblStartPosLTc.Visible = checkedValue;
            nudStartPosT.Visible = checkedValue;
        }

        private void cboConClient_SelectedIndexChanged(object sender, EventArgs e) {
            switch (cboConClient.Text) {
                default:
                    btnConCdkeyManager.Visible = false;
                    lblConCdkey.Visible = false;
                    txtConCdkey.Visible = false;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = -1;
                    cbAdvPlug.Enabled = false;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "Chat":
                    btnConCdkeyManager.Visible = false;
                    lblConCdkey.Visible = false;
                    txtConCdkey.Visible = false;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = -1;
                    cbAdvPlug.Enabled = false;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "Diablo: Shareware":
                    btnConCdkeyManager.Visible = false;
                    lblConCdkey.Visible = false;
                    txtConCdkey.Visible = false;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0x2A;
                    cbAdvPlug.Enabled = true;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "Diablo":
                    btnConCdkeyManager.Visible = false;
                    lblConCdkey.Visible = false;
                    txtConCdkey.Visible = false;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0x2A;
                    cbAdvPlug.Enabled = true;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "Diablo II":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0x0C;
                    cbAdvPlug.Enabled = false;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = true;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "Diablo II: Lord of Destruction":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = true;
                    txtConExpCdkey.Visible = true;
                    nudAdvVerbyte.Value = 0x0C;
                    cbAdvPlug.Enabled = false;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = true;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "StarCraft: Shareware":
                    btnConCdkeyManager.Visible = false;
                    lblConCdkey.Visible = false;
                    txtConCdkey.Visible = false;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0xA5;
                    cbAdvPlug.Enabled = true;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "StarCraft: Japan":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0xA9;
                    cbAdvPlug.Enabled = true;
                    cbConSpawn.Visible = true;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "StarCraft":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0xD1;
                    cbAdvPlug.Enabled = true;
                    cbConSpawn.Visible = true;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "StarCraft: Broodwar":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0xD1;
                    cbAdvPlug.Enabled = true;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "WarCraft II: Battle.net Edition":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = false;
                    txtConExpCdkey.Visible = false;
                    nudAdvVerbyte.Value = 0x4F;
                    cbAdvPlug.Enabled = true;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
                case "WarCraft III":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    bool vis = (cbConUseTFTKey.Checked);
                    lblConExpCdkey.Visible = vis;
                    txtConExpCdkey.Visible = vis;
                    nudAdvVerbyte.Value = 0x16;
                    cbAdvPlug.Enabled = false;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = true;
                    break;
                case "WarCraft III: The Frozen Throne":
                    btnConCdkeyManager.Visible = true;
                    lblConCdkey.Visible = true;
                    txtConCdkey.Visible = true;
                    lblConExpCdkey.Visible = true;
                    txtConExpCdkey.Visible = true;
                    nudAdvVerbyte.Value = 0x16;
                    cbAdvPlug.Enabled = false;
                    cbConSpawn.Visible = false;
                    cbConD2Realm.Visible = false;
                    cbConUseTFTKey.Visible = false;
                    break;
            }
            switch (cboConClient.Text) {
                default:
                    cbConD2Realm.Visible = false;
                    break;
                case "Diablo II":
                case "Diablo II: Lord of Destruction":
                    cbConD2Realm.Visible = true;
                    break;
            }
            if (cboConClient.Text != "")
                btnAdvVerbyte.Text = "Get Verbyte for \"" + cboConClient.Text + "\"";
            else
                btnAdvVerbyte.Text = "Get Verbyte for Product";
        }

        private void btnConCdkeyManager_Click(object sender, EventArgs e) {
            new frmCDKeyManager(this).ShowDialog(this);
        }

        private void cbConUseTFTKey_CheckedChanged(object sender, EventArgs e) {
            bool vis = (cboConClient.Text != "WarCraft III");
            lblConExpCdkey.Visible = vis;
            txtConExpCdkey.Visible = vis;
        }

        private void cbAdvChangePass_CheckedChanged(object sender, EventArgs e) {
            if (cbAdvChangePass.Checked) {
                MessageBox.Show("Enter a new password. " +
                                "The next time you log on, the password will be " +
                                "changed and this option will be disabled again. " +
                                "The old password will be replaced with the new " +
                                "one as well.",
                                "Felbot",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }
            txtAdvChangePass.Visible = cbAdvChangePass.Checked;
        }

        private void cbAdvSpoof_CheckedChanged(object sender, EventArgs e) {
            cboAdvSpoof.Visible = cbAdvSpoof.Checked;
        }

        private void cbProxyUse_CheckedChanged(object sender, EventArgs e) {
            bool checkedValue = cbAdvProxyUse.Checked;
            cboAdvProxyProtocol.Visible = checkedValue;
            lblAdvProxyServer.Visible = checkedValue;
            txtAdvProxyServer.Visible = checkedValue;
            lblAdvProxyPort.Visible = checkedValue;
            nudAdvProxyPort.Visible = checkedValue;
        }

        private void btnAdvHashesBrowse_Click(object sender, EventArgs e) {
            folderBrowser.Description = "Choose the folder where you have placed hash files in subfolders.";
            if (folderBrowser.ShowDialog() == DialogResult.OK) {
                txtAdvHashes.Text = folderBrowser.SelectedPath + "\\";
            }
            if (txtAdvHashes.Text.StartsWith(Environment.CurrentDirectory)) {
                txtAdvHashes.Text = txtAdvHashes.Text.Remove(0, Environment.CurrentDirectory.Length);
            }
        }

        #region Get Verbyte
        /// <summary>This is used for the verbyte thread.</summary>
        private delegate void VerbyteDelegate();
        /// <summary>This is used for the verbyte form load event.</summary>
        private delegate void VerbyteLoadDelegate(object sender, EventArgs e);

        private void btnAdvVerbyte_Click(object sender, EventArgs e) {
            if (cboConClient.Text == "") {
                MessageBox.Show("Select a client on the Connection tab to get a verbyte.",
                                "Felbot",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return;
            }
            using (Form frmVerbyte = new Form())
            using (Label lblVerbyte = new Label()) {
                frmVerbyte.FormBorderStyle = FormBorderStyle.FixedDialog;
                frmVerbyte.Text = "Felbot Verbyte Fetcher";
                frmVerbyte.Size = new Size(400, 100);
                frmVerbyte.UseWaitCursor = true;
                frmVerbyte.ShowInTaskbar = false;
                frmVerbyte.StartPosition = FormStartPosition.CenterScreen;

                lblVerbyte.Text = "Getting verbyte for " + cboConClient.Text + "...";
                lblVerbyte.AutoSize = true;
                lblVerbyte.Location = new Point((int) (frmVerbyte.Width / 2 - (lblVerbyte.Width / 2)), (int) (frmVerbyte.Height / 2 - (lblVerbyte.Height / 2)));

                frmVerbyte.Controls.Add(lblVerbyte);
                frmVerbyte.Load += new EventHandler((VerbyteLoadDelegate) frmVerbyte_Load);
                frmVerbyte.ShowDialog();
            }
        }

        public void frmVerbyte_Load(object sender, EventArgs e) {
            new Thread(new ThreadStart((VerbyteDelegate) delegate() {
                string client = "";
                byte verbyte;
                this.Invoke((VerbyteDelegate) delegate() {
                    switch (cboConClient.Text) {
                        case "StarCraft: Shareware":
                            client = "SSHR";
                            break;
                        case "StarCraft: Japan":
                            client = "JSTR";
                            break;
                        case "StarCraft":
                            client = "STAR";
                            break;
                        case "StarCraft: Broodwar":
                            client = "SEXP";
                            break;
                        case "Diablo: Shareware":
                            client = "DSHR";
                            break;
                        case "Diablo":
                            client = "DRTL";
                            break;
                        case "Diablo II":
                            client = "D2DV";
                            break;
                        case "Diablo II: Lord of Destruction":
                            client = "D2XP";
                            break;
                        case "WarCraft II: Battle.net Edition":
                            client = "W2BN";
                            break;
                        case "WarCraft III":
                            client = "WAR3";
                            break;
                        case "WarCraft III: The Frozen Throne":
                            client = "W3XP";
                            break;
                        case "Chat":
                            client = "CHAT";
                            break;
                        default:
                            client = "";
                            break;
                    }

                    if (client == "") {
                        MessageBox.Show("Invalid client!",
                                        "Felbot",
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Error);
                        (sender as Form).Close();
                        return;
                    }
                });

                try {
                    verbyte = CheckRevision.GetVersionByte(client);
                } catch (WebException) {
                    MessageBox.Show("Request timed out.\r\n" +
                                    "Unable to access verbyte server.\r\n" +
                                    "Check your internet connection and try again." +
                                    "Also make sure that you can access the following site. (You should see a \"-1\".\r\n" +
                                    "http://www.jinxbot.net/mbncsutil/mbncsutil_bytes.aspx?Client=",
                                    "Felbot",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation);
                    (sender as Form).Close();
                    return;
                }

                if (verbyte > 0) {
                    MessageBox.Show("Verbyte found! 0x" + verbyte.ToString("X") + " (" + verbyte.ToString() + "d)",
                                    "Felbot",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                    (sender as Form).Close();
                    this.Invoke((VerbyteDelegate) delegate() {
                        nudAdvVerbyte.Value = (decimal) verbyte;
                    });
                } else {
                    MessageBox.Show("Client not supported.",
                                    "Felbot",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation);
                    (sender as Form).Close();
                }
            })).Start();
        }
        #endregion
    }
}
